/*
 * GToe: Gtk+ TicTacToe
 * minimax.c: minimax algorithm
 *
 * Copyright (C) 2010 Dani El-Soufi <danisoufi@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "../include/minimax.h"

int mini(const MATRIX * matrix, const char minp, const char maxp,
         const int depth, const int nrounds, const int max_depth);

int evaluate(const MATRIX * matrix, const char p1, const char p2);

int position;

int
max(const MATRIX * matrix, const char maxp, const char minp,
    const int depth, const int nrounds, const int max_depth)
{
     int alfa = INT_MIN;
     int node = 0;

     for (int i = 0; i < NUM_ALL; ++i)
     {
        if (place_stone(matrix, minp, i))
        {
           if (depth >= max_depth || game_winner(matrix, maxp, minp) != ' ')
           {
              node = evaluate(matrix, maxp, minp);
           }
           else
           {
              node = mini(matrix, minp, maxp, depth + 1, nrounds, max_depth);
           }
           *(matrix + i) = ' ';
           if (node > alfa)
           {
              alfa = node;
              if (depth == nrounds)
              {
                 position = i;
              }
           }
        }
     }
     return alfa;
}

int
mini(const MATRIX * matrix, const char minp, const char maxp,
     const int depth, const int nrounds, const int max_depth)
{
     int alfa = INT_MAX;
     int node = 0;

     for (int i = 0; i < NUM_ALL; ++i)
     {
        if (place_stone(matrix, maxp, i))
        {
           if (depth >= max_depth || game_winner(br, minp, maxp) != ' ')
           {
              node = -evaluate(matrix, minp, maxp);
           }
           else
           {
              node = max(matrix, maxp, minp, depth + 1, nrounds, max_depth);
           }
           *(matrix + i) = ' ';
           if (node < alfa)
           {
              alfa = node;
           }
        }
     }
     return alfa;
}

int
evaluate(const MATRIX * matrix, const char p1, const char p2)
{
     char winner = game_winner(matrix, p1, p2);

     if (winner == p1)
     {
        return -1;
     }
     else if (winner == p2)
     {
        return 1;
     }
     else
     {
        return 0;
     }
}
